package com.linchong.concurrency.other;

import lombok.extern.slf4j.Slf4j;

/**
 * @Author:linchong
 * @CreateTime:2020-01-08 11:02
 * @Description:Synchronized测试
 */
@Slf4j
public class SynchronizeTest {

	public static void main(String[] args) throws InterruptedException {
		//synchronized代码块之间同步性：
		//synchronized (this)同步代码块,对象监视器为同一个
		CommonService commonService = new CommonService();
		ThreadA threadA = new ThreadA(commonService);
		threadA.setName("Thread-A");
		ThreadB threadB = new ThreadB(commonService);
		threadB.setName("Thread-B");
		ThreadC threadC = new ThreadC(commonService);
		threadC.setName("Thread-C");
		ThreadD threadD = new ThreadD(commonService);
		threadD.setName("Thread-D");
		ThreadE threadE = new ThreadE(commonService);
		threadE.setName("Thread-E");
		ThreadF threadF = new ThreadF(commonService);
		threadF.setName("Thread-F");

//		log.info("调用同一个实例的Synchronized(this)修饰的两个方法【同步】\n");
//		threadA.start();
//		threadB.start();

		//synchronized (this)代码块是锁定当前对象
//		threadA.join();
//		threadB.join();


//		Thread.sleep(6_000);
//		log.info("调用同一个实例的Synchronized修饰的和未被修饰的方法【异步】\n");
//		threadC.start();
//		threadD.start();
//
//		threadC.join();
//		threadD.join();
//		Thread.sleep(6_000);
//		log.info("调用同一个实例的Synchronized修饰的不同方法【同步】\n");

//		threadE.start();
//		threadF.start();
//		log.info("from above,we can know that:\n{}\n1.{}\n2.{}\n",
//				"多个线程调用同一个对象中的不同名称的synchronized同步方法或synchronized(this)同步代码块时，是同步的",
//				"synchronized同步方法时,其它的synchronized同步方法或synchronized(this)同步代码块调用被堵塞",
//				"同一时间只有一个线程执行synchronized同步方法中的代码");


//		threadE.join();
//		threadF.join();

//		CommonService commonService1 = new CommonService();
//		ThreadH threadH = new ThreadH(commonService1);
//		ThreadG threadG = new ThreadG(commonService1);
//		threadH.setName("Thread-H");
//		threadG.setName("Thread-G");
//		threadH.start();
//		threadG.start();

//		CommonService commonService2 = new CommonService();
//		ThreadI threadI = new ThreadI(commonService2);
//		ThreadJ threadJ = new ThreadJ(commonService2);
//		threadI.setName("Thread-I");
//		threadJ.setName("Thread-J");
//		threadI.start();
//		threadJ.start();

		CommonService commonService2 = new CommonService();
		ThreadK threadK = new ThreadK(commonService2);
		ThreadL threadL = new ThreadL(commonService2);
		threadK.start();
		threadL.start();


	}


}

class ThreadL extends Thread {
	private CommonService commonService;

	public ThreadL(CommonService commonService) {
		this.commonService = commonService;
	}

	@Override
	public void run() {
		this.commonService.testM4();
	}
}

class ThreadK extends Thread {
	private CommonService commonService;

	public ThreadK(CommonService commonService) {
		this.commonService = commonService;
	}

	@Override
	public void run() {
		this.commonService.testM7();
	}
}


class ThreadJ extends Thread {
	private CommonService commonService;

	public ThreadJ(CommonService commonService) {
		this.commonService = commonService;
	}

	@Override
	public void run() {
		this.commonService.testM6("marry", 16);
	}
}

class ThreadI extends Thread {
	private CommonService commonService;

	public ThreadI(CommonService commonService) {
		this.commonService = commonService;
	}

	@Override
	public void run() {
		this.commonService.testM6("tony", 14);
	}
}

class ThreadH extends Thread {
	private CommonService commonService;

	public ThreadH(CommonService commonService) {
		this.commonService = commonService;
	}

	@Override
	public void run() {
		this.commonService.testM5("jerry", 10);
	}
}

class ThreadG extends Thread {
	private CommonService commonService;

	public ThreadG(CommonService commonService) {
		this.commonService = commonService;
	}

	@Override
	public void run() {
		this.commonService.testM5("tom", 8);
	}
}


class ThreadF extends Thread {
	private CommonService commonService;

	public ThreadF(CommonService commonService) {
		this.commonService = commonService;
	}

	@Override
	public void run() {
		this.commonService.testM4();
	}
}

class ThreadE extends Thread {
	private CommonService commonService;

	public ThreadE(CommonService commonService) {
		this.commonService = commonService;
	}

	@Override
	public void run() {
		this.commonService.testSynchronizedM1();
	}
}

class ThreadD extends Thread {
	private CommonService commonService;

	public ThreadD(CommonService commonService) {
		this.commonService = commonService;
	}

	@Override
	public void run() {
		this.commonService.testSynchronizedM2();
	}
}

class ThreadC extends Thread {
	private CommonService commonService;

	public ThreadC(CommonService commonService) {
		this.commonService = commonService;
	}

	@Override
	public void run() {
		this.commonService.testM3();
	}
}

class ThreadA extends Thread {
	private CommonService commonService;

	public ThreadA(CommonService commonService) {
		this.commonService = commonService;
	}

	@Override
	public void run() {
		commonService.testSynchronizedM1();
	}
}

class ThreadB extends Thread {
	private CommonService commonService;

	public ThreadB(CommonService commonService) {
		this.commonService = commonService;
	}

	@Override
	public void run() {
		commonService.testSynchronizedM2();
	}
}
